<h1>Garbage Collector Interface</h1>

<h1>Public Interface</h1>

	<p>The public interface of the Mono GC is fairly limited, and
	its the only one that embedders should be using:

<h3>Garbage Collector</h3>

<h4><a name="api:mono_gc_collect">mono_gc_collect</a></h4> 
<h4><a name="api:mono_gc_collection_count">mono_gc_collection_count</a></h4>
<h4><a name="api:mono_gc_max_generation">mono_gc_max_generation</a></h4> 
<h4><a name="api:mono_gc_get_generation">mono_gc_get_generation</a></h4>
<h4><a name="api:mono_gc_get_heap_size">mono_gc_get_heap_size</a></h4> 
<h4><a name="api:mono_gc_get_used_size">mono_gc_get_used_size</a></h4> 
<h4><a name="api:mono_gc_walk_heap">mono_gc_walk_heap</a></h4>

<h3>Reference Queues</h3>

<h4><a name="api:mono_gc_reference_queue_add">mono_gc_reference_queue_add</a></h4>
<h4><a name="api:mono_gc_reference_queue_free">mono_gc_reference_queue_free</a></h4>
<h4><a name="api:mono_gc_reference_queue_new">mono_gc_reference_queue_new</a></h4>

<h3>SGen Bridge</h3>

	<p>The bridge is a mechanism for SGen to let clients override
	the death of some unreachable objects.  We use it in monodroid
	to do garbage collection across the Mono and Java heaps.

	<p>The client can designate some objects as "bridged", which
	means that they participate in the bridge processing step once
	SGen considers them unreachable, i.e., dead.  Bridged objects
	must be registered for finalization.

	<p>When SGen is done marking, it puts together a list of all
	dead bridged objects and then does a strongly connected
	component analysis over their object graph.  That graph will
	usually contain non-bridged objects, too.
	
	<p>The output of the SCC analysis is passed to the
	`cross_references()` callback.  It is expected to set the
	`is_alive` flag on those strongly connected components that it
	wishes to be kept alive.  The value of `is_alive` will be
	ignored on any SCCs which lack bridges.
	
	<p>In monodroid each bridged object has a corresponding Java
	mirror object.  In the bridge callback it reifies the Mono
	object graph in the Java heap so that the full, combined
	object graph is now instantiated on the Java side.  Then it
	triggers a Java GC, waits for it to finish, and checks which
	of the Java mirror objects are still alive.  For those it sets
	the `is_alive` flag and returns from the callback.
	
	<p>The SCC analysis is done while the world is stopped, but
	the callback is made with the world running again.  Weak links
	to bridged objects and other objects reachable from them are
	kept until the callback returns, at which point all links to
	bridged objects that don't have `is_alive` set are nulled.
	Note that weak links to non-bridged objects reachable from
	bridged objects are not nulled.  This might be considered a
	bug.

<div class="mapi-header">
enum {
        SGEN_BRIDGE_VERSION = 5
};
        
typedef enum {
        /* Instances of this class should be scanned when computing the transitive dependency among bridges. E.g. List of object*/
        GC_BRIDGE_TRANSPARENT_CLASS,
        /* Instances of this class should not be scanned when computing the transitive dependency among bridges. E.g. String*/
        GC_BRIDGE_OPAQUE_CLASS,
        /* Instances of this class should be bridged and have their dependency computed. */
        GC_BRIDGE_TRANSPARENT_BRIDGE_CLASS,
        /* Instances of this class should be bridged but no dependencies should not be calculated. */
        GC_BRIDGE_OPAQUE_BRIDGE_CLASS,
} MonoGCBridgeObjectKind;

typedef struct {
        mono_bool is_alive;     /* to be set by the cross reference callback */
        int num_objs;
        MonoObject *objs [MONO_ZERO_LEN_ARRAY];
} MonoGCBridgeSCC;

typedef struct {
        int src_scc_index;
        int dst_scc_index;
} MonoGCBridgeXRef;

typedef struct {
        int bridge_version;
        /*
         * Tells the runtime which classes to even consider when looking for
         * bridged objects.  If subclasses are to be considered as well, the
         * subclass check must be done in the callback.
         */
        MonoGCBridgeObjectKind (*bridge_class_kind) (MonoClass *klass);
        /*
         * This is only called on objects for whose classes
         * `bridge_class_kind()` returned `XXX_BRIDGE_CLASS`.
         */
        mono_bool (*is_bridge_object) (MonoObject *object);
        void (*cross_references) (int num_sccs, MonoGCBridgeSCC **sccs, int num_xrefs, MonoGCBridgeXRef *xrefs);
} MonoGCBridgeCallbacks;
</div>

<h4><a name="api:mono_gc_register_bridge_callbacks">mono_gc_register_bridge_callbacks</a></h4>
<h4><a name="api:mono_gc_wait_for_bridge_processing">mono_gc_wait_for_bridge_processing</a></h4>

<h3>Write Barriers</h3>

	<p>SGen is a concurrent and generational GC, features which require
	tracking changes to the state of the heap. This is achieved through
	write barriers. Whenever native code is changing the state of the
	heap by storing references into another managed object, it needs to
	do it using this write barrier API.

<h4><a name="api:mono_gc_wbarrier_arrayref_copy">mono_gc_wbarrier_arrayref_copy</a></h4>
<h4><a name="api:mono_gc_wbarrier_generic_nostore">mono_gc_wbarrier_generic_nostore</a></h4>
<h4><a name="api:mono_gc_wbarrier_generic_store">mono_gc_wbarrier_generic_store</a></h4>
<h4><a name="api:mono_gc_wbarrier_generic_store_atomic">mono_gc_wbarrier_generic_store_atomic</a></h4>
<h4><a name="api:mono_gc_wbarrier_object_copy">mono_gc_wbarrier_object_copy</a></h4>
<h4><a name="api:mono_gc_wbarrier_set_arrayref">mono_gc_wbarrier_set_arrayref</a></h4>
<h4><a name="api:mono_gc_wbarrier_set_field">mono_gc_wbarrier_set_field</a></h4>
<h4><a name="api:mono_gc_wbarrier_value_copy">mono_gc_wbarrier_value_copy</a></h4>

